/*
 * Created on 2006-8-2 上午07:17:12
 */
package cn.com.sbell.vss.csg.heartbeat;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

public class HeartBeatMessageEncoder extends ProtocolEncoderAdapter {
	private static Log logger = LogFactory.getLog(HeartBeatMessageEncoder.class);
	//消息由消息头和消息体组成.消息体中包括多个消息属性.
	private final static int VERSION=0x10;
	private final static int RESERVEDVALUE=0;
	
	//消息属性格式:return properties:Type-Reserved-Length-Value
	
	//各消息属性type字段需要填的值
	private final static int NTPSERVER_TYPEVALUE=5;
	private final static int SERVERTIME_TYPEVALUE=6;
	private final static int TIMEZONE_TYPEVALUE=7;	
	private final static int REGISTER_RESULT=8;
//	added ms property
	private final static int MS_USERNAME=11;
	private final static int MS_PASSWORD=12;
	
	
	//各个消息属性大小(字节)
	private final static int TYPE_LENGTH=1;
	private final static int RESERVED_LENGTH=1;
	private final static int LENGTH_LENGTH=2;
	private final static int COMMON_PART_LENGTH=TYPE_LENGTH+RESERVED_LENGTH+LENGTH_LENGTH;
	
	private final static int NTPSERVERIP_IP_LENGTH=4;
	private final static int NTPSERVERIP_PORT_LENGTH=2;
	private final static int NTPSERVERIP_RESERVED_LENGTH=2;
	private final static int NTPSERVERIP_VALUE_LENGTH=NTPSERVERIP_IP_LENGTH+NTPSERVERIP_PORT_LENGTH+NTPSERVERIP_RESERVED_LENGTH;
	private final static int NTPSERVERIP_TOTAL_LENGTH=COMMON_PART_LENGTH+NTPSERVERIP_VALUE_LENGTH;
	
	private final static int SERVERTIME_VALUE_LENGTH=19;
	private final static int SERVERTIME_TOTAL_LENGTH=COMMON_PART_LENGTH+SERVERTIME_VALUE_LENGTH;
	
	private final static int TIMEZONE_VALUE_LENGTH=1;
	private final static int TIMEZONE_TOTAL_LENGTH=COMMON_PART_LENGTH+TIMEZONE_VALUE_LENGTH;
	
	private final static int REGISTERRESULT_VALUE_LENGTH=2;
	private final static int REGISTERRESULT_TOTAL_LENGTH=COMMON_PART_LENGTH+REGISTERRESULT_VALUE_LENGTH;
		
	
	
	
	//消息总大小.
	private final static int HEAD_LENGTH = 4;
	private final static int TOTAL__BODY_LENGTH = NTPSERVERIP_TOTAL_LENGTH+SERVERTIME_TOTAL_LENGTH+TIMEZONE_TOTAL_LENGTH+REGISTERRESULT_TOTAL_LENGTH;
	private final static int TOTAL_LENGTH=HEAD_LENGTH+TOTAL__BODY_LENGTH;
	
	public void encode(IoSession session, Object responseInfoToVS,
			ProtocolEncoderOutput out) throws Exception {
		logger.info("Into the encode Method of HeartBeatMessageEncoder,the sesseion is "+session.getRemoteAddress());
		if(responseInfoToVS instanceof ResponseInfoToVS)
		{
			logger.info("The message to encode is RegisterVSResponseInfo");
			ResponseInfoToVS responseInfo=(ResponseInfoToVS)responseInfoToVS;
			
			ByteBuffer buf = ByteBuffer.allocate( TOTAL_LENGTH );
			buf.setAutoExpand( true );
			
			//消息头
			buf.put((byte) VERSION);//版本号
			buf.put((byte) responseInfo.getRequestMessageType());//请求的消息类型
			int totalLength=getTotalLength(responseInfo);
			buf.putShort((short) totalLength);//消息头和消息体的全部长度
			
			//消息属性部分
			//NTPIP
			if(null!=responseInfo.getNtpIp())
			{
				putNTPIPValueIntoBuffer(responseInfo,buf);
			}
			//SERVERTIME
			if(null!=responseInfo.getCurrentTime())
			{
				putServerTimeValueIntoBuffer(responseInfo,buf);
			}
			//TIMEZONE
			if(null!=responseInfo.getTimezone())
			{
				putTIMEZONEValueIntoBuffer(responseInfo,buf);			
			}
			//RESULT_CODE
			if(null!=responseInfo.getReturnCodeByEMS())
			{
				putResultCodeIntoBuffer(responseInfo,buf);
			}
			if(null!=responseInfo.getMsUserName())
			{
				putMSUserName(responseInfo,buf);
			}
			if(null!=responseInfo.getMsPassWord())
			{
				putMSPassWord(responseInfo,buf);
			}
//			added vondart change total length
			buf.putShort(2, (short)buf.position());
	        buf.flip();
	        out.write( buf );
		}
	}
	
	private void putResultCodeIntoBuffer(ResponseInfoToVS responseInfo, ByteBuffer buf) {
		putCommonPartIntoBuffer(buf,REGISTER_RESULT,REGISTERRESULT_TOTAL_LENGTH);
		String resultcode=responseInfo.getReturnCodeByEMS();
		buf.putShort((short) Integer.valueOf(resultcode).intValue());
	}

	/*
	 * 包括IP+Port+保留字
	 */
	private void putNTPIPValueIntoBuffer(ResponseInfoToVS responseInfo,ByteBuffer buf)
	{
		putCommonPartIntoBuffer(buf,NTPSERVER_TYPEVALUE,NTPSERVERIP_TOTAL_LENGTH);
		String ipStr=responseInfo.getNtpIp();
		String[] ipArray=ipStr.split("\\.");
		for(int i=0;i<ipArray.length;i++)
		{
			buf.put((byte) Integer.valueOf(ipArray[i]).byteValue());
		}
		String portStr=responseInfo.getNtpPort();
		buf.putShort(Integer.valueOf(portStr).shortValue());
		buf.putShort((short) RESERVEDVALUE);
	}
	
	private void putTIMEZONEValueIntoBuffer(ResponseInfoToVS responseInfo, ByteBuffer buf) {
		putCommonPartIntoBuffer(buf,TIMEZONE_TYPEVALUE,TIMEZONE_TOTAL_LENGTH);
		String timezone=responseInfo.getTimezone();
		buf.put(Integer.valueOf(timezone).byteValue());
	}

	private void putServerTimeValueIntoBuffer(ResponseInfoToVS responseInfo, ByteBuffer buf) {
		putCommonPartIntoBuffer(buf,SERVERTIME_TYPEVALUE,SERVERTIME_TOTAL_LENGTH);		
		String serverTime=responseInfo.getCurrentTime();
		buf.put(serverTime.getBytes());
	}

	private void putMSUserName(ResponseInfoToVS responseInfo, ByteBuffer buf)
	{
		byte[] msUserName=responseInfo.getMsUserName().getBytes();
		putCommonPartIntoBuffer(buf,MS_USERNAME,COMMON_PART_LENGTH+msUserName.length);
		buf.put(msUserName);
		
	}
	private void putMSPassWord(ResponseInfoToVS responseInfo, ByteBuffer buf)
	{
		byte[] msPassWord=responseInfo.getMsPassWord().getBytes();
		putCommonPartIntoBuffer(buf,MS_PASSWORD,COMMON_PART_LENGTH+msPassWord.length);
		buf.put(msPassWord);
		
	}
	
	private int getTotalLength(ResponseInfoToVS responseInfo)
	{
		int totalLength=0;
		totalLength+=HEAD_LENGTH;
		if(null!=responseInfo.getNtpIp())
		{
			totalLength+=NTPSERVERIP_TOTAL_LENGTH;
		}
		if(null!=responseInfo.getCurrentTime())
		{
			totalLength+=SERVERTIME_TOTAL_LENGTH;
		}
		if(null!=responseInfo.getTimezone())
		{
			totalLength+=TIMEZONE_TOTAL_LENGTH;
		}
		//RESULT_CODE
		if(null!=responseInfo.getReturnCodeByEMS())
		{
			totalLength+=REGISTERRESULT_TOTAL_LENGTH;
		}
		return totalLength;
	}
		
	/*
	 * 消息属性公共部分:属性类型+保留字+消息属性长度
	 */
	private void putCommonPartIntoBuffer(ByteBuffer buf,int type,int totallength)
	{
		buf.put((byte) type);//属性类型
		buf.put((byte) RESERVEDVALUE);//保留字
		buf.putShort((short) totallength);//消息属性长度
	}
}
